#pragma once
#include "Astronomy/Coordinate.hpp"

class CelestialSun
{
public:
    /*
     * @brief [S_Lon]计算太阳地心黄道经度;
     *
     * @param T
     *        儒略世纪数;
     *
     * @param CalcItemsCount
     *        参与计算数量 默认：-1 全部参与计算;
     *
     * @return 太阳黄经(单位：度);
     */
    static double GeometricEclipticLongitude(const double T, int CalcItemsCount = -1) noexcept;
    /*
     * @brief 计算太阳黄道纬度;
     *
     * @param T
     *        儒略世纪数;
     *
     * @param CalcItemsCount
     *        参与计算数量 默认：-1 全部参与计算;
     *
     * @return 太阳黄纬度(单位：度);
     */
    static double GeometricEclipticLatitude(const double T, int CalcItemsCount = -1) noexcept;
    /*
     * @brief 计算太阳视黄道经度;
     *
     * @param T
     *        儒略世纪数;
     *
     * @param CalcItemsCount
     *        参与计算数量 默认：-1 全部参与计算;
     *
     * @return 太阳视黄经(单位：角秒);
     */
    static double ApparentEclipticLongitude(double JD, int CalcItemsCount = -1) noexcept;
    /*
     * @brief 计算太阳视黄道纬度;
     *
     * @param T
     *        儒略世纪数;
     *
     * @param CalcItemsCount
     *        参与计算数量 默认：-1 全部参与计算;
     *
     * @return 太阳视黄纬(单位：角秒);
     */
    static double ApparentEclipticLatitude(double JD, int CalcItemsCount = -1) noexcept;
    /*
     * @brief 计算太阳视黄道坐标;
     * 包含 ApparentEclipticLatitude,ApparentEclipticLongitude;
     * @param T
     *        儒略世纪数;
     *
     * @param bHighPrecision
     *        启用高经度[默认：不启用];
     *
     * @return 太阳视黄纬(单位：角秒)[X = Longitude,Y = Latitude, Z = R];
     */
    static Coordinate3D ApparentEclipticLocation(const double T, bool bHighPrecision = false) noexcept;

    /*
     * @brief 太阳光行差修正量- [高精度];
     *
     * @param T
     *        儒略世纪数;
     *
     * @return 太阳黄经的修正参数 Δλ(单位是角秒/日);
     */
    static double VariationEclipticLongitudeHigh(const double T) noexcept;
    /*
     * @brief [gxc_sunLon] 太阳光行差修正量-(黄经) [中精度];
     *
     * @param T
     *        儒略世纪数;
     *
     * @return 太阳黄经的修正参数 Δλ(单位是角秒/日);
     */
    static double VariationEclipticLongitude(double T) noexcept;
    /*
     * @brief [gxc_sunLat]太阳光行差修正量-(黄纬) [中精度];
     *
     * @param T
     *        儒略世纪数;
     *
     * @return 太阳黄纬的修正参数 Δλ(单位是角秒/日);
     */
    static double VariationEclipticLatitude(double T) noexcept { return 0.0; }
    /**
     * @brief [S_aLon_t] 已知太阳视黄经反求时间;
     *
     * @param W
     *        太阳真黄经值;
     * @return double
     */
    static double GetEclipticLongitudeTime(double W) noexcept;

    /**
     * @brief [S_aLon_t2] 已知太阳视黄经反求时间,高速低精度,最大误差不超过600秒;
     *
     * @param W
     *        太阳真黄经值;
     * @return double
     */
    static double GetEclipticLongitudeTimeLow(double W) noexcept;

    /**
     * @brief 太阳升降计算;
     * [sunShengJ]
     * @param jd
     *        儒略日(须接近L当地平午UT);
     * @param L
     *        地理经度;
     * @param fa
     *        地理纬度;
     * @param sj
     *         sj=-1升,sj=1降[默认];
     * @return double 格林尼治UT
     */
    static double RiseSet(double jd, double L, double fa, double sj = 1);

    /**
     * @brief 平太阳与真太阳时差计算,低精度,误差约在1秒以内;
     * [pty_zty2]
     * @param t
     *         力学时儒略世纪数;
     * @return double 单位是周(天)
     */
    static double CalcTimeDifferenceLow(double t) noexcept;

    /**
     * @brief 平太阳与真太阳时差计算,高精度;
     * [pty_zty]
     * @param t
     *         力学时儒略世纪数;
     * @return double 单位是周(天)
     */
    static double CalcTimeDifferenceHigh(double t) noexcept;
};
